///////////////////////////////////////////////////////////////////////////////////////////////////
/// \file matrix_actor.h
///
/// \brief   header file for the matrix actor class
///
///////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef PCPS_MATRIX_ACTOR_HEADER
#define PCPS_MATRIX_ACTOR_HEADER

namespace pcps {

  ///////////////////////////////////////////////////////////////////////////////////////////////////
  /// \brief  Base class for operating by a square matrix A and its
  ///         approximation M.
  ///
  ///         M is intended to be used as a preconditioner in iterative
  ///         methods.
  ///
  ///////////////////////////////////////////////////////////////////////////////////////////////////
  template<class SCALAR> class MatrixActor {

    public:

      // function to perform y = A d
      virtual void operate_by_A(const int n, SCALAR * const d, SCALAR * const y, const int myrank, const int tid) = 0;

      // function to perform y = M d
      virtual void operate_by_M(const int n, SCALAR * const d, SCALAR * const y, const int myrank, const int tid) = 0;

      // function to perform y = M^(-1) d
      virtual void operate_by_M_inv(const int n, SCALAR * const d, SCALAR * const y, const int myrank, const int tid) = 0;

      // function to check if the iterations have converged
      // result should be computed using the root process/thread and returned on all processes/threads
      virtual bool converged(const double residual, const int myrank, const int tid) = 0;

      // make destructor virtual
      virtual ~MatrixActor() {}

  };

} // end namespace pcps

#endif
